package com.fitso.model.dao.hibernate;

import java.util.List;

import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.joda.time.DateTime;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;

import com.fitso.model.bean.User;
import com.fitso.model.bean.journal.FoodJournal;
import com.fitso.model.bean.journal.FoodJournalEntry;
import com.fitso.model.dao.FoodJournalDao;

@Repository("HibernateFoodJournalDao")
public class HibernateFoodJournalDao extends HibernateBaseDao implements FoodJournalDao {

	/**
	 * Utility method for creating a criteria that is between the high and lo of
	 * a given date. So if the date provided is 2010.03.16 14:22:38 this will
	 * return a criteria for lo = 2010.03.16 00:00:00 and hi = 2010.03.17
	 * 00:00:00.
	 * 
	 * @param propertyName
	 * @param date
	 * @return
	 */
	private Criterion between(String propertyName, DateTime date) {
		DateTime lo = date.toDateMidnight().toDateTime();
		DateTime hi = date.plusDays(1).toDateMidnight().toDateTime();

		return Restrictions.between(propertyName, lo, hi);
	}

	public void delete(FoodJournal journal) {
		if (journal != null) {
			HibernateTemplate template = getTemplate();
			template.deleteAll(journal.getEntries());
			template.deleteAll(journal.getRemovedEntries());
		}
	}

	public FoodJournal read(User user, DateTime date) {

		if (user == null || date == null) {
			return null;
		}

		DetachedCriteria c = DetachedCriteria.forClass(FoodJournalEntry.class).add(Restrictions.eq("user", user))
				.add(between("at", date));

		List<FoodJournalEntry> entries = toList(t().findByCriteria(c), FoodJournalEntry.class);

		if (entries == null || entries.isEmpty()) {
			return null;
		}
		return new FoodJournal(entries);
	}

	public void createOrUpdate(FoodJournal journal) {
		if (journal != null) {
			HibernateTemplate template = getTemplate();
			template.saveOrUpdateAll(journal.getEntries());
			template.deleteAll(journal.getRemovedEntries());
		}
	}
}
